package com.sd.repay.service.impl;

import com.sd.repay.common.CommonResult;
import com.sd.repay.common.Constants;
import com.sd.repay.dao.BaseDao;
import com.sd.repay.pojo.ExtractionOrder;
import com.sd.repay.pojo.ReverseRecord;
import com.sd.repay.service.BalanceOperService;
import com.sd.repay.service.ExtractOrderService;
import com.sd.repay.service.ReverseRecordService;
import com.sd.repay.utils.WebUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author sd
 * @Description: 冲正记录Service接口实现类
 * @date 2017年10月25日
 */
@Service
public class ReverseRecordServiceImpl implements ReverseRecordService {

    private static Logger log = LoggerFactory.getLogger(ReverseRecordServiceImpl.class);

    @Autowired
    private BaseDao baseDao;
    @Autowired
    private BalanceOperService balanceOperService;
    @Autowired
    private ExtractOrderService extractOrderService;

    /**
     * 执行冲正
     *
     * @param extOrder
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public CommonResult executeReverse(ExtractionOrder extOrder) throws Exception {

        String extOrderNo = extOrder.getOrderNo();
        String merType = extOrder.getMerType();
        String merNo = extOrder.getMerNo();
        BigDecimal amount = extOrder.getAmount();

        //查询是否已存在冲正记录
        String cbSql = "SELECT * FROM t_reverse_record WHERE service_order_no = ? AND service = ? ";
        ReverseRecord reverseRecord = baseDao.findFirst(ReverseRecord.class, cbSql, new Object[]{extOrderNo, Constants.WITHDRAW_SERVICE_WITHDRAW});
        if (reverseRecord != null && Constants.REVERSE_STATUS_SUCCESS.equals(reverseRecord.getStatus())) {
            return CommonResult.ok("已冲正成功");
        }

        //如果不存在则新增冲正记录
        String reverseOrderNo = "";
        int count;
        if (reverseRecord == null) {

            reverseOrderNo = WebUtil.nextUniqueSeqNo("t_reverse_record", "REO", 20);
            reverseRecord = new ReverseRecord();
            reverseRecord.setOrderNo(reverseOrderNo);
            reverseRecord.setMerType(merType);
            reverseRecord.setMerNo(merNo);
            reverseRecord.setService(Constants.WITHDRAW_SERVICE_WITHDRAW);
            reverseRecord.setServiceOrderNo(extOrderNo);
            reverseRecord.setAmount(amount);
            reverseRecord.setServiceTime(extOrder.getCreateTime());

            count = saveReversrRecord(reverseRecord);
            log.info("提现订单号{}新增冲正{}记录影响的行数{}", new Object[]{extOrderNo, reverseOrderNo, count});
            if (count < 1) {
                return CommonResult.build(403, "新增冲正记录失败");
            }
        }
        reverseOrderNo = reverseRecord.getOrderNo();

        //跟新用户余额
        try {
            CommonResult balanceUpdateRes = balanceOperService.updateBalance(merNo, merType, amount, Constants.BALANCE_HIS_TRANS_TYPE_IN, Constants.BALANCE_HIS_TYPE_CURR,
                    Constants.BALANCE_HIS_SERVICE_REVERSE, reverseOrderNo, "提现冲正", Constants.BALANCE_CHANNEL_DAIFU);

            String reverseStatus = Constants.REVERSE_STATUS_INIT;
            String reverseRemark = "冲正初始化";
            if (balanceUpdateRes == null || balanceUpdateRes.getStatus() != 200) {
                reverseStatus = Constants.REVERSE_STATUS_FAIL;
                reverseRemark = "冲正失败";
            } else {
                reverseStatus = Constants.REVERSE_STATUS_SUCCESS;
                reverseRemark = "冲正成功";
            }
            //回写冲正状态
            count = updateReverseStatus(reverseOrderNo, reverseStatus, Constants.REVERSE_STATUS_INIT, reverseRemark);
            log.info("提现订单号{}回写冲正{}状态{}记录影响的行数{}", new Object[]{extOrderNo, reverseOrderNo, reverseStatus, count});
            if (count < 1) {
                throw new RuntimeException("提现订单号" + extOrderNo + "回写冲正" + reverseOrderNo + "状态" + reverseStatus + "失败");
            }
            //回写提现订单冲正状态
            count = extractOrderService.updateExtractReverseStatus(extOrderNo, reverseStatus, "", "", reverseRemark);
            log.info("提现订单号{}回写冲正状态{}记录影响的行数{}", new Object[]{extOrderNo, reverseStatus, count});
            if (count < 1) {
                throw new RuntimeException("提现订单号" + extOrderNo + "回写冲正状态" + reverseStatus + "失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.info("{}/{}提现订单号{}冲正异常{}", new Object[]{merType, merNo, extOrderNo, e});
            return CommonResult.build(403, "冲正异常");
        }


        return CommonResult.ok();
    }

    /**
     * 修改冲正记录状态
     *
     * @param reverseOrderNo
     * @param newStatus
     * @param oldStatus
     * @param remark
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    public int updateReverseStatus(String reverseOrderNo, String newStatus, String oldStatus, String remark) throws Exception {

        String sql = " UPDATE t_reverse_record SET status = ?, back_remark = ? WHERE order_no = ? ";
        List<Object> params = new ArrayList<>();
        params.add(newStatus);
        params.add(remark);
        params.add(reverseOrderNo);

        if (StringUtils.isNotBlank(oldStatus)) {
            sql += " AND status = ? ";
            params.add(oldStatus);
        }
        return baseDao.execute(sql, params.toArray());
    }


    /**
     * 新增冲正记录
     *
     * @param record
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public int saveReversrRecord(ReverseRecord record) throws Exception {

        String sql = "INSERT INTO t_reverse_record (order_no,mer_type,mer_no,service,service_order_no,amount,service_time,create_time) VALUES " +
                " (?,?,?,?,?,?,?,?) ";
        List<Object> params = new ArrayList<>();
        params.add(record.getOrderNo());
        params.add(record.getMerType());
        params.add(record.getMerNo());
        params.add(record.getService());
        params.add(record.getServiceOrderNo());
        params.add(record.getAmount());
        params.add(record.getServiceTime());
        params.add(new Date());
        return baseDao.execute(sql, params.toArray());
    }

    @Override
    public ReverseRecord getReverseRecordByService(String service, String serviceOrderNo) throws Exception {

        String sql = " SELECT * FROM t_reverse_record WHERE service = ? AND service_order_no = ? ";
        return baseDao.findFirst(ReverseRecord.class, sql, new Object[]{service, serviceOrderNo});
    }
}
